
import 'package:xim/common/util/datetime.dart';
import 'package:xim/http/apis/gfs/gfs_api.dart';
import 'package:xim/http/apis/secret/secret_model.dart';
import 'package:xim/http/apis/user/user_model.dart';
import 'package:xim/http/ase.dart';
import 'package:xim/http/rsa.dart';
import 'package:xim/widget/dash_chat_2/dash_chat_2.dart';

/// 聊天消息 [java:ChatMessage]
class ChatMessageModel {

  /// 消息Id
  final int id;

  /// 会话Id
  final int sessionId;

  /// 消息内容
  final String content;

  /// 发送者账号
  final String senderAccount;

  /// 发送者信息
  final UserInfoModel userInfo;

  /// 方式时间
  final DateTime sendTime;

  /// 会话密钥
  final SessionSecretKeyModel secretKey;

  /// 消息类型
  final ChatMessageType chatMessageType;

  /// 附件
  final String? attachment;

  ChatMessageModel({
    required this.id,
    required this.sessionId,
    required this.content,
    required this.senderAccount,
    required this.sendTime,
    required this.secretKey,
    required this.userInfo,
    required this.chatMessageType,
    this.attachment,
  });

  MessageType getMessageType() => MessageType.chatMessage;


  Map<String, dynamic> toJson() => {
    "id": id,
    "sessionId": sessionId,
    "messageType": getMessageType().typeCode,
    "content": content,
    "senderAccount": senderAccount,
    "sendTime": sendTime.format("yyyy-MM-dd HH:mm:ss"),
    "user": userInfo.toJson(),
    "secretKey": secretKey.toJson(),
    "chatMessageType": chatMessageType.code,
    "attachment": attachment,
  };

  ChatMessageModel.fromJson(Map<String, dynamic> json):
        id = json['id'],
        sessionId = json['sessionId'],
        content = json['content'],
        senderAccount = json['senderAccount'],
        sendTime = DateTime.parse(json['sendTime']),
        userInfo = UserInfoModel.fromJson(json['userInfoVo']),
        secretKey = SessionSecretKeyModel.fromJson(json['secretKeyVo']),
        chatMessageType = ChatMessageType.of(json['chatMessageType'])!,
        attachment = json['attachment']
  ;

  /// 解密
  /// plaintextAESKey AES明文密钥
  String decodeContentByPlaintextAESKey(String plaintextAESKey){
    return AES.decryptAes(encryptedBase64Text: content, aseKey: plaintextAESKey);
  }

  /// 解密
  /// ciphertextAESKey AES密文密钥
  /// privateKey 用户私钥
  String decodeContentByCiphertextAESKey(String privateKey,{String? ciphertextAESKey}){
    var plaintextAESKey = decodeByPrivateKeySync(privateKey, ciphertextAESKey??secretKey.secretKey);
    return decodeContentByPlaintextAESKey(plaintextAESKey);
  }

}

/// 消息大类型
enum MessageType {
  chatMessage(typeCode:1),
  authMessage(typeCode:2),
  ;

  final int typeCode;

  const MessageType({required this.typeCode});

}

/// 聊天消息类型 [java:ChatMessageType]
enum ChatMessageType {

  /// 文本消息
  text(1),

  /// 图片消息
  image(1 << 1),

  /// 视频
  video(1 << 2),

  /// 语音
  voice(1 << 3),

  /// 表情包
  faceIcon(1 << 4),

  /// 文件
  file(1 << 5),

  ;
  final int code;

  const ChatMessageType(this.code);

  static ChatMessageType? of(int code){
    for(var item in ChatMessageType.values){
      if(item.code == code) {
        return item;
      }
    }
    return null;
  }

  /// 类型转换
  static ChatMessageType? fromMediaType(MediaType mediaType){
    if(mediaType == MediaType.file){
      return ChatMessageType.file;
    }
    if(mediaType == MediaType.image){
      return ChatMessageType.image;
    }
    if(mediaType == MediaType.video){
      return ChatMessageType.video;
    }
    return null;
  }

  /// 类型转换
  MediaType toMediaType(){
    if(this == ChatMessageType.image){
      return MediaType.image;
    }
    if(this == ChatMessageType.file){
      return MediaType.file;
    }
    if(this == ChatMessageType.video){
      return MediaType.video;
    }
    return MediaType.file;
  }

}

/// [java:ChatMessageStoreVo]
class ChatMessageStoreModel {

  /// 用户账号
  final String userAccount;

  /// 会话密钥版本
  final int secretVersion;

  /// 会话账号
  final int sessionId;

  /// 消息内容
  final String content;

  /// 消息附件
  final String? attachment;

  final ChatMessageType chatMessageType;

  ChatMessageStoreModel({
      required this.userAccount,
      required this.secretVersion,
      required this.sessionId,
      required this.content,
      this.attachment,
      this.chatMessageType = ChatMessageType.text,
    }
  );

  Map<String, dynamic> toJson()=>{
    "userAccount":userAccount,
    "secretVersion":secretVersion,
    "sessionId":sessionId,
    "content":content,
    "chatMessageType":chatMessageType.code,
    "attachment":attachment,
  };

}


extension ChatMessageExtension on ChatMessage {

  int get messageId => customProperties!['messageId']!;

  SessionSecretKeyModel get secretKey => customProperties!['secretKey']!;

}